package com.dotflat.refund.controller;

import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.StatusResponse;
import com.matt.domain.Clientele;
import com.matt.domain.Contract;
import com.matt.domain.ContractProduct;
import com.matt.domain.Product;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.model.MemVerificationCache;
import com.matt.foundation.utils.DateUtil;
import com.matt.foundation.vo.ContractVo;
import com.matt.repository.ProductRepository;
import com.matt.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.matt.foundation.constant.CommonConstant.TICKET;


/**
 * @author ：Ron
 * @date ：Created in 11/6/2020 5:07 PM
 */
@RestController
@RequestMapping("/fin/refund_product")
@Slf4j
@Api(tags = "财务 - 退费产品 - 补充接口")
public class RefundProductController{

    @Autowired
    protected MemVerificationCache cache;

    @Autowired
    private ProductService productService;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private ContractService contractService;

    @Autowired
    private ClienteleService clienteleService;

    @Autowired
    private ContractProductService contractProductService;

    @Autowired
    private TeachCallService teachCallService;


    @ApiOperation(value = "进行中合同列表", response = Contract.class)
    @GetMapping("/inprogress_contract")
    public StatusResponse inprogressContract(@RequestHeader(TICKET) String ticket, String clienteleId){
        StaffDTO staff = cache.getStaff(ticket);
        String areaId = staff.getAreaId();

        List<Contract> contracts = contractService.contractsByClientele(areaId, clienteleId);

        return StatusResponse.success(contracts);
    }


    @ApiOperation(value = "可退款产品列表", response = ContractProduct.class)
    @GetMapping("/refundable_products")
    public StatusResponse refundableProducts(@RequestHeader(TICKET) String ticket, String clienteleId){
        StaffDTO staff = cache.getStaff(ticket);
        String areaId = staff.getAreaId();

        Clientele clientele = clienteleService.getById(areaId, clienteleId);

        if (clientele == null){
            throw new BusinessException(ErrorCode.CLIENTELE_EXIST, "客户不存在");
        }

        List<ContractProduct> results = contractProductService.findByClienteleId(clienteleId);

        List<String> pids = results.stream().map(o->o.getProductId()).collect(Collectors.toList());
        List<Product> ps = productService.findAllByIds(areaId, pids);

        Map<String, Product> cache = ps.stream().collect(Collectors.toMap(Product::getId, o->o));
        for (ContractProduct cp : results){
            Product p = cache.get(cp.getProductId());
            if (p != null){
                cp.setProductName(p.getName());
            }
        }

        return StatusResponse.success(results);
    }

    @ApiOperation(value = "建议退款金额")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "ticket", value = "票据", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "clienteleId", value = "客户 id", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "refundCPId", value = "为可退款列表内 id 字段", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "endDate", value = "结束日期(不传为当日)", required = true, dataType = "Date")
    })
    @GetMapping("/recommend_refund")
    public StatusResponse getList(@RequestHeader(TICKET) String ticket, String clienteleId, String refundCPId,Date endDate){
        StaffDTO staff = cache.getStaff(ticket);
        String areaId = staff.getAreaId();

        Clientele c = clienteleService.getById(areaId, clienteleId);
        if (c == null){
            throw new BusinessException(ErrorCode.CLIENTELE_EXIST, "指定客户不存在");
        }

        ContractProduct cp = contractProductService.get(clienteleId, refundCPId);

        ContractVo contractVo = contractService.details(cp.getContractId());

        Product product = productRepository.findByIdAndAreaId(cp.getProductId(),areaId);
        if (product == null){
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXIST, "产品不存在");
        }
        if (Objects.isNull(endDate)){
            endDate= new Date();
        }
        //当结束时间大于合同结束时间，赋值合同结束时间
        if (endDate.getTime()>contractVo.getEndDate().getTime()){
            endDate= contractVo.getEndDate();
        }
        if (endDate.getTime()<=contractVo.getBeginDate().getTime()){
            endDate= contractVo.getBeginDate();
        }
        //需要根据product的refundPlicy配置方案，计算recommendRefund，建议退费金额。
        //需要自动生成退费建议文案。
        double month = DateUtil.betweenMonthsV2(contractVo.getEndDate(),contractVo.getBeginDate());
        //合同开始到结束 多少天的正常天
        int day  = (int)Math.ceil((month)*28.5);
        if (day==0){
            day = DateUtil.birthdayDay(contractVo.getEndDate(),contractVo.getBeginDate());
        }
        //请假总天数
        Long newDay = teachCallService.findLeaveCountByDateAndClienteleId(ticket,cp.getClienteleId(),contractVo.getBeginDate(),endDate);

        //剩余多少天
        Integer surplusDay = 0;
        if (endDate.getTime()<contractVo.getEndDate().getTime()){
            surplusDay = DateUtil.birthdayDay(contractVo.getEndDate(),endDate);
            newDay+=surplusDay;
        }
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        //已完成合同数量的百分比 0.01
        Double percentage = 0.0 ;
        if (day !=0 && newDay !=0){
            percentage =  Double.valueOf(numberFormat.format((float)newDay  / (float) day * 100))/100;
        }

        //合同总金额
        double standardTotalAmount  = cp.getStandardTotalAmount().doubleValue();

        Map ret = new HashMap();
        ret.put("product", product);
        ret.put("contractProduct", cp);
        ret.put("recommendRefund", standardTotalAmount*percentage);
        ret.put("recommendRemark", "退费策略:根据出勤比例退费；合同共"+day+"天，共请假【"+newDay+"】天。");

        return StatusResponse.success(ret);
    }


}
